// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
@file:Suppress("LiftReturnOrAssignment")

package com.intellij.ui

import com.intellij.testFramework.PlatformTestUtil
import com.intellij.ui.scale.paint.ImageComparator
import com.intellij.ui.svg.renderSvg
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.intellij.lang.annotations.Language
import org.junit.jupiter.api.Assumptions.assumeTrue
import org.junit.jupiter.api.Test
import java.awt.Image
import java.awt.image.BufferedImage
import java.nio.file.FileVisitResult
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.SimpleFileVisitor
import java.nio.file.attribute.BasicFileAttributes
import javax.imageio.ImageIO
import kotlin.io.path.inputStream

internal object IntelliJIconsIconsVerifier {
  @JvmStatic
  fun main(args: Array<String>) {
    runBlocking(Dispatchers.IO) {
      val list = mutableListOf<Pair<Path, ByteArray>>()
      val root = Path.of(System.getProperty("user.home"), "projects/IntelliJIcons")
      Files.walkFileTree(root, object : SimpleFileVisitor<Path>() {
        override fun visitFile(file: Path, attrs: BasicFileAttributes): FileVisitResult {
          if (attrs.isRegularFile && file.toString().endsWith(".svg")) {
            list.add(file to Files.readAllBytes(file))
          }
          return FileVisitResult.CONTINUE
        }
      })

      println("icons: ${list.joinToString(separator = "\n") { it.first.toString() }}")

      // process in parallel to test concurrent rendering
      repeat(4) {
        for ((_, data) in list) {
          launch {
            renderSvg(data = data, scale = 2f)
          }
        }
      }
    }
  }
}

class SvgRenderingTest {
  @Test
  fun filter() {
    assumeTrue(System.getenv("TEAMCITY_VERSION") == null)
    @Language("HTML")
    val svg = """
      <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
        <defs>
          <linearGradient id="safari-a" x1="50%" x2="50%" y1="100%" y2="0%">
            <stop offset="25%" stop-color="#DBDBDA"/>
            <stop offset="100%" stop-color="#FFF"/>
          </linearGradient>
          <radialGradient id="safari-b" cx="57.025%" cy="39.017%" r="61.032%" fx="57.025%" fy="39.017%">
            <stop offset="0%" stop-color="#2ABCE1"/>
            <stop offset="11.363%" stop-color="#2ABBE1"/>
            <stop offset="100%" stop-color="#3375F8"/>
          </radialGradient>
          <linearGradient id="safari-c" x1="50%" x2="50%" y1="0%" y2="100%">
            <stop offset="0%" stop-color="#676767" stop-opacity=".387"/>
            <stop offset="100%" stop-opacity=".387"/>
          </linearGradient>
          <filter id="safari-d" width="100%" height="100%" x="0%" y="0%" filterUnits="objectBoundingBox">
            <feGaussianBlur in="SourceGraphic"/>
          </filter>
          <polygon id="safari-e" points="1.073 .119 2.147 6.173 0 6.173"/>
          <polygon id="safari-g" points="1.073 .119 2.147 6.173 0 6.173"/>
        </defs>
        <g fill="none" fill-rule="evenodd" transform="translate(1 1)">
          <circle cx="7" cy="7" r="7" fill="url(#safari-a)" fill-rule="nonzero"/>
          <circle cx="7" cy="7" r="6.364" fill="url(#safari-b)" fill-rule="nonzero"/>
          <path fill="#F4F2F3" fill-rule="nonzero" d="M6.9999989,1 C6.94882061,1 6.90761944,1.04115888 6.90761944,1.09228956 L6.90761944,2.15681847 C6.90761944,2.20794915 6.94882061,2.24910804 6.9999989,2.24910804 C7.05117939,2.24910804 7.09237836,2.20794915 7.09237836,2.15681847 L7.09237836,1.09228956 C7.09237836,1.04115888 7.05117939,1 6.9999989,1 Z M6.39564999,1.03815945 C6.38952677,1.03750168 6.38322797,1.03750168 6.37686333,1.03823619 C6.32595937,1.0435422 6.28925735,1.08875295 6.29457292,1.13960737 L6.34114014,1.58495953 C6.34645132,1.63581395 6.3917083,1.67248245 6.44260786,1.66717205 C6.49351401,1.66186604 6.53021823,1.61665529 6.52490047,1.56580088 L6.47837275,1.1204509 C6.47371998,1.07595274 6.43847963,1.04231436 6.3956434,1.03815945 L6.39564999,1.03815945 Z M7.60857482,1.03859796 C7.5657364,1.04271999 7.53049166,1.07635617 7.52580377,1.12084776 L7.47891832,1.56616265 C7.47356324,1.61701268 7.51026966,1.66226509 7.56117142,1.66761276 C7.61206878,1.67296262 7.65732357,1.6363292 7.66267865,1.58547917 L7.70956629,1.140127 C7.71492137,1.08927697 7.67821276,1.04406184 7.62731319,1.03871636 C7.62094855,1.03805859 7.61469365,1.03805859 7.60857043,1.03860235 L7.60857482,1.03859796 Z M5.77483421,1.12809858 C5.76868904,1.12814681 5.76243414,1.12875635 5.75617923,1.13007189 C5.70610927,1.14066199 5.67432996,1.18946636 5.68493038,1.2394876 L5.9056122,2.28091562 C5.91621262,2.33093686 5.96506233,2.36268305 6.0151323,2.35209514 C6.06520226,2.34150503 6.09698157,2.29273794 6.08638335,2.2427167 L5.86570152,1.20125141 C5.85641793,1.15748118 5.81787454,1.12770611 5.7748386,1.12804157 L5.77483421,1.12809858 Z M8.22935109,1.1289756 C8.18631515,1.12853709 8.14775201,1.15834286 8.13844866,1.20210432 L7.91700967,2.24340955 C7.90636535,2.29342422 7.93812271,2.34224174 7.98817732,2.35286692 C8.0382407,2.36350087 8.08710577,2.33177442 8.09773911,2.28176633 L8.31917811,1.2404589 C8.32982242,1.19044643 8.29806506,1.14162672 8.24801046,1.13100373 C8.24175555,1.12968819 8.23550065,1.12903042 8.22935548,1.12903042 L8.22935109,1.1289756 Z M5.18236303,1.29499026 C5.1704019,1.29389397 5.1580523,1.29520951 5.14588267,1.29924384 C5.09720854,1.31505225 5.07074041,1.36688455 5.08655764,1.41551132 L5.22506538,1.84138691 C5.24088919,1.89001587 5.29281149,1.91645604 5.34148562,1.9006564 C5.39016195,1.88484799 5.41658837,1.83297622 5.40077115,1.78434945 L5.2622656,1.35847386 C5.2504142,1.32200269 5.21824205,1.29802916 5.18236303,1.29498149 L5.18236303,1.29499026 Z M8.81847095,1.29520951 C8.78259194,1.29825718 8.75043734,1.32223072 8.73857058,1.3586997 L8.59998164,1.78453582 C8.58415783,1.83316039 8.610604,1.88503655 8.65926936,1.90084277 C8.70794349,1.91665118 8.75986798,1.89023074 8.77569179,1.84161494 L8.91427854,1.41573935 C8.93010235,1.36711258 8.90365617,1.31523862 8.85499082,1.2994324 C8.84283216,1.29548578 8.83042989,1.29419216 8.81847095,1.29520074 L8.81847095,1.29520951 Z M4.59647377,1.5091822 C4.58446874,1.50940146 4.57232325,1.51203254 4.56063207,1.51722892 C4.51388927,1.53799254 4.49295619,1.59231121 4.51374442,1.63903264 L4.94653337,2.61179163 C4.96731721,2.65851086 5.02168879,2.67940165 5.06845573,2.65863365 C5.11519852,2.63787003 5.13617111,2.58355136 5.11538288,2.53682993 L4.68255224,1.56407094 C4.66696984,1.52902713 4.63247569,1.50848716 4.59647377,1.50918439 L4.59647377,1.5091822 Z M9.41097944,1.51244913 C9.37497972,1.51179136 9.34045923,1.53220416 9.32482197,1.56721728 L8.89071401,2.53937989 C8.86986433,2.58607281 8.89070523,2.64043095 8.93744363,2.66126254 C8.98418424,2.68209193 9.03859313,2.6612735 9.0594472,2.61458058 L9.49355077,1.64242016 C9.51440046,1.59572504 9.49356175,1.5413669 9.44682334,1.52053532 C9.43514752,1.51533893 9.42298008,1.51270785 9.41097944,1.51244474 L9.41097944,1.51244913 Z M4.052646,1.79664537 C4.03491279,1.79532983 4.01663969,1.79927645 4.0000192,1.8088799 C3.95569497,1.83444524 3.94061955,1.89066706 3.9662076,1.93494597 L4.19031975,2.32274323 C4.21590999,2.36702433 4.27218219,2.38208508 4.31650642,2.35651974 C4.36082846,2.3309544 4.37590607,2.27473477 4.35031802,2.23045367 L4.12620588,1.8426586 C4.11020649,1.81498182 4.08220865,1.79871735 4.052646,1.79665195 L4.052646,1.79664537 Z M9.94734961,1.79664537 C9.91779135,1.79861868 9.88982424,1.81497524 9.87383143,1.84265202 L9.64967978,2.23044709 C9.62408954,2.27472819 9.63921105,2.33094782 9.68353089,2.35651316 C9.72785512,2.3820785 9.78412951,2.36701556 9.80971976,2.32273665 L10.0338297,1.93493939 C10.05942,1.89066048 10.0443423,1.83443866 10.0000181,1.80887332 C9.9834042,1.7992918 9.96508721,1.79541096 9.94734961,1.79663879 L9.94734961,1.79664537 Z M3.52456961,2.12569059 C3.50679252,2.12634836 3.48899128,2.13204904 3.47345497,2.14329691 C3.43202994,2.17331974 3.42287144,2.23080448 3.45293449,2.27219139 L4.07861373,3.13385955 C4.10866581,3.17524646 4.16624605,3.18439604 4.20767327,3.15438198 C4.24910049,3.12435915 4.25825899,3.06687441 4.22819375,3.0254875 L3.602475,2.16381934 C3.58368834,2.13795143 3.55418275,2.12468859 3.52456961,2.12569936 L3.52456961,2.12569059 Z M10.4820474,2.13038269 C10.4524343,2.1292864 10.4229199,2.14255144 10.4041003,2.16838208 L9.77722717,3.02921487 C9.74711584,3.07056012 9.75620191,3.12806898 9.79759402,3.15814882 C9.83898174,3.18822646 9.89654662,3.17917554 9.92665575,3.13784564 L10.5534916,2.27701285 C10.5835985,2.2356654 10.5744949,2.17815874 10.5331248,2.1480789 C10.5176082,2.1368091 10.4998179,2.13102072 10.4820496,2.13038488 L10.4820474,2.13038269 Z M3.05254596,2.52116623 C3.02896606,2.51985069 3.00490333,2.527722 2.98588403,2.54482623 C2.94784543,2.57903467 2.94478821,2.63715306 2.97903656,2.67515464 L3.2789384,3.00798424 C3.31317797,3.04598582 3.37135517,3.04904226 3.40939377,3.01482505 C3.44743237,2.9806166 3.45049179,2.92245875 3.41624124,2.88445716 L3.11637891,2.55166704 C3.09926022,2.53265747 3.07613024,2.52239406 3.05254596,2.52115526 L3.05254596,2.52116623 Z M10.9481278,2.521824 C10.9245457,2.52313954 10.9014201,2.53333498 10.8842971,2.55233358 L10.5843952,2.88508424 C10.5501447,2.92308143 10.5531778,2.98123929 10.5912207,3.01545212 C10.6292528,3.04966495 10.68743,3.04659755 10.7216761,3.00861131 L11.0216175,2.67586284 C11.0558658,2.63786345 11.0527932,2.57970559 11.01477,2.54549496 C10.9957419,2.52839293 10.9717297,2.52060054 10.9481454,2.52183496 L10.9481278,2.521824 Z M2.60014295,2.9553056 C2.57656086,2.95662114 2.55347038,2.96681658 2.5363495,2.98581738 C2.50210774,3.02381896 2.50516935,3.08193735 2.54319698,3.11614579 L3.33513598,3.82836635 C3.37317458,3.86257698 3.43134958,3.85951616 3.46558915,3.82152553 C3.49983311,3.78352614 3.496811,3.72540556 3.45876362,3.69119711 L2.66678731,2.97897656 C2.64775924,2.96187454 2.62370528,2.95407776 2.600121,2.95531657 L2.60014295,2.9553056 Z M11.4027277,2.95841905 C11.3791456,2.95710351 11.3550544,2.9649529 11.3360241,2.98203958 L10.5436067,3.69370541 C10.5055461,3.72788535 10.5024165,3.78600594 10.5366275,3.82403164 C10.5708429,3.86205515 10.6290618,3.86514448 10.6671224,3.83096015 L11.4595793,3.11929651 C11.4976399,3.08511438 11.50073,3.0269938 11.4665146,2.9889681 C11.4493959,2.96995853 11.4263032,2.9596732 11.4027233,2.95841905 L11.4027277,2.95841905 Z M2.22392907,3.438587 C2.19431374,3.43749072 2.16478401,3.45082153 2.14598418,3.47666532 C2.11590138,3.51803031 2.12502476,3.57550628 2.16643881,3.6055598 L2.5290565,3.86876441 C2.57046178,3.89882012 2.62799154,3.88974728 2.65807434,3.84837353 C2.68815934,3.80700854 2.67905571,3.74949311 2.6376636,3.71943958 L2.27504591,3.45623498 C2.25952936,3.44496518 2.24170178,3.43922065 2.22393346,3.43858481 L2.22392907,3.438587 Z M11.7785817,3.44194163 C11.7608046,3.4425994 11.7430033,3.44827815 11.7274692,3.45954795 L11.3646913,3.72251575 C11.3232663,3.75254077 11.3141034,3.81006279 11.3441489,3.8514497 C11.3742054,3.89283441 11.4317439,3.90194673 11.4731689,3.87192828 L11.8359885,3.60896267 C11.8774136,3.57893765 11.8865347,3.52145291 11.8564871,3.48006819 C11.8377004,3.45420247 11.8081948,3.44093743 11.7785817,3.4419504 L11.7785817,3.44194163 Z M1.87235513,3.95409256 C1.84279467,3.95606588 1.81482976,3.97242243 1.79883476,4.00009702 C1.77324452,4.04437593 1.78832213,4.10059775 1.83264417,4.12616309 L2.75543578,4.65842645 C2.79975781,4.68399179 2.8560344,4.66892885 2.88162464,4.62464994 C2.90721489,4.58037104 2.89213727,4.52414922 2.84781524,4.49858388 L1.92502363,3.96631832 C1.90840972,3.9567368 1.89009053,3.95285596 1.87235513,3.95408379 L1.87235513,3.95409256 Z M12.1276427,3.95409256 C12.1099095,3.95277702 12.0915947,3.95672365 12.0749742,3.96632709 L11.1521826,4.49859265 C11.1078605,4.52415799 11.0927829,4.58037981 11.1183732,4.62465871 C11.1439634,4.66893762 11.20024,4.68400056 11.244562,4.65843522 L12.1673953,4.12617186 C12.2117174,4.10060652 12.2267928,4.0443847 12.2012026,4.00010579 C12.1852032,3.9724312 12.1572031,3.95616454 12.1276427,3.95410133 L12.1276427,3.95409256 Z M1.60654142,4.5035632 C1.5705417,4.50268617 1.53601902,4.52327438 1.52038175,4.55828969 C1.49953207,4.604987 1.52036859,4.65934733 1.56711138,4.68017453 L1.97649381,4.86260055 C2.02323661,4.88342994 2.07764989,4.8626159 2.09849738,4.81592078 C2.11934706,4.76922347 2.09847104,4.71486314 2.05173044,4.69403594 L1.64238532,4.51160992 C1.6307095,4.50639161 1.61853987,4.50380438 1.60654142,4.5035632 Z M12.3952516,4.50735634 C12.3832466,4.5075756 12.3710572,4.51020668 12.3593661,4.51540306 L11.9499024,4.69751116 C11.9031465,4.71831863 11.8822397,4.77264388 11.9030543,4.81935434 C11.923882,4.86606481 11.9783019,4.88695121 12.0250578,4.86615689 L12.4345237,4.68400714 C12.4812774,4.66322159 12.5021447,4.60887442 12.4813301,4.56216395 C12.4657258,4.52713111 12.4312514,4.50664156 12.3952516,4.50735634 Z M1.36963416,5.07786027 C1.33375295,5.08086409 1.30158518,5.10480912 1.28969428,5.14127152 C1.27384852,5.18988514 1.30022885,5.24177664 1.34890079,5.25761794 L2.36203957,5.58741959 C2.41069834,5.60324993 2.46264258,5.57687334 2.47849931,5.52827069 C2.49434507,5.47965708 2.46796474,5.42776339 2.4192928,5.41192428 L1.40615622,5.08212043 C1.39399756,5.07815188 1.3815931,5.07685827 1.36963416,5.07786685 L1.36963416,5.07786027 Z M12.63172,5.0818069 C12.6197588,5.08071061 12.6074071,5.08202615 12.5952374,5.08606048 L11.5818638,5.41514735 C11.5331897,5.43095577 11.5067545,5.48282973 11.5225761,5.5314543 C11.5383999,5.58007888 11.5903222,5.60649055 11.6389963,5.59068433 L12.6523326,5.26159745 C12.7010068,5.24578904 12.7274793,5.19391508 12.7116599,5.1452905 C12.6997865,5.10882152 12.6675968,5.08484141 12.63172,5.08180032 L12.63172,5.0818069 Z M1.22203596,5.68071116 C1.17899782,5.68027265 1.14040177,5.71011788 1.13109183,5.75387934 C1.12044752,5.80389181 1.15220488,5.85270494 1.20225948,5.8633367 L1.64071076,5.95642217 C1.69077195,5.96705612 1.73963044,5.93532967 1.75027255,5.88532377 C1.76091687,5.83530911 1.72915951,5.78649598 1.6791049,5.77586641 L1.24069313,5.68278094 C1.23443823,5.6814654 1.22818332,5.68080763 1.22203815,5.68080763 L1.22203596,5.68071116 Z M12.7781638,5.68158819 C12.7720186,5.68163862 12.7658076,5.68246521 12.7595527,5.6835615 L12.3210992,5.77660749 C12.271038,5.78724145 12.2393004,5.83601073 12.2499337,5.8860254 C12.2605781,5.93603787 12.3094322,5.96778625 12.3594955,5.95716326 L12.7979073,5.86411726 C12.8479685,5.8534833 12.8797478,5.80467455 12.8691145,5.75465989 C12.8598089,5.71089843 12.8212063,5.68112775 12.7781725,5.68149171 L12.7781638,5.68158819 Z M1.11031897,6.28710304 C1.06747835,6.29120314 1.03221605,6.32478232 1.02751061,6.3692739 C1.02213358,6.42011955 1.05874563,6.46539169 1.1096408,6.47076348 L2.16930729,6.58268968 C2.22020247,6.58806147 2.2655187,6.55144559 2.27089573,6.50059775 C2.27627275,6.4497521 2.2396212,6.40447996 2.18872383,6.39910817 L1.12905954,6.28718197 C1.1226949,6.2865242 1.11643999,6.2865242 1.11031677,6.28710524 L1.11031897,6.28710304 Z M12.8906752,6.29506206 C12.884552,6.29440429 12.8782532,6.29440429 12.8718886,6.2951388 L11.8121036,6.40563106 C11.7611996,6.41093708 11.7245042,6.45614782 11.729811,6.50700005 C11.7351222,6.55785446 11.7803769,6.59452297 11.8312809,6.58921257 L12.8910659,6.47872031 C12.9419677,6.47341429 12.9786653,6.42820355 12.9733585,6.37734913 C12.9687057,6.33285316 12.9335027,6.29921917 12.8906665,6.29505768 L12.8906752,6.29506206 Z M1.09237726,6.90782555 C1.04119678,6.90782555 1,6.94898443 1,7.00011511 C1,7.0512436 1.04119678,7.09240248 1.09237726,7.09240248 L1.54059717,7.09240248 C1.59177546,7.09240248 1.63301613,7.0512436 1.63301613,7.00011511 C1.63301613,6.94898443 1.59177546,6.90782555 1.54059717,6.90782555 L1.09237726,6.90782555 Z M12.4594006,6.90782555 C12.4082223,6.90782555 12.3670212,6.94898443 12.3670212,7.00011511 C12.3670234,7.0512436 12.4082223,7.09240248 12.4594006,7.09240248 L12.9076205,7.09240248 C12.9587988,7.09240248 13,7.0512436 13,7.00011511 C13,6.94898443 12.9587988,6.90782555 12.9076205,6.90782555 L12.4594006,6.90782555 Z M2.18748821,7.41093434 C2.18136499,7.41027657 2.17511009,7.41027657 2.16874545,7.41101108 L1.10891874,7.52150333 C1.05801479,7.52680935 1.02132154,7.57202009 1.02662834,7.62287232 C1.03193952,7.67372673 1.07719431,7.71039524 1.12809606,7.70508484 L2.18792277,7.59459258 C2.23882672,7.58928657 2.27551997,7.54407582 2.27021317,7.4932214 C2.2655604,7.44872543 2.23032005,7.41509144 2.18748383,7.41093214 L2.18748821,7.41093434 Z M11.8119521,7.41746819 C11.7691093,7.42156829 11.733847,7.45514966 11.7291416,7.49964124 C11.7237646,7.55048689 11.7603788,7.59575903 11.811274,7.60113082 L12.8709405,7.71305701 C12.9218378,7.71842881 12.9671497,7.68181073 12.9725289,7.63096509 C12.9779059,7.58011944 12.9412522,7.5348473 12.890357,7.52947551 L11.8307322,7.41754931 C11.8243676,7.41689154 11.8180688,7.41689154 11.8119456,7.41747257 L11.8119521,7.41746819 Z M1.65920992,8.04094675 C1.65306475,8.04099937 1.64680984,8.04160452 1.64055494,8.04292006 L1.20210366,8.13596387 C1.15204028,8.14659782 1.12030487,8.19540657 1.13093601,8.24542123 C1.14158032,8.2954359 1.19043662,8.32714262 1.2405,8.31651963 L1.67895128,8.2235131 C1.72901246,8.21287914 1.76075007,8.16407039 1.75011673,8.11405792 C1.74081119,8.07029427 1.70225025,8.04052578 1.65921431,8.04088755 L1.65920992,8.04094675 Z M12.3406672,8.04182378 C12.2976312,8.04138526 12.2590747,8.07119103 12.2497648,8.11495249 C12.2391204,8.16496496 12.2708339,8.21378029 12.3208929,8.22440986 L12.7593442,8.31749532 C12.8094032,8.32812927 12.858266,8.29644667 12.868906,8.24643639 C12.8795503,8.19642392 12.8477929,8.14756913 12.7977405,8.13693956 L12.3593265,8.0438541 C12.3530716,8.04253855 12.3468167,8.04188078 12.3406716,8.04188078 L12.3406672,8.04182378 Z M2.39752134,8.40532301 C2.3855602,8.40422672 2.37321061,8.40554226 2.36104098,8.40957659 L1.34766737,8.73866127 C1.29899323,8.75446969 1.27255803,8.80634365 1.28837965,8.85496822 C1.30420346,8.90359499 1.35612576,8.93000227 1.40479989,8.91419825 L2.41813619,8.58511137 C2.46681032,8.56930296 2.49328503,8.517429 2.47746341,8.46880442 C2.46559007,8.43233544 2.43340035,8.40835533 2.39752134,8.40531424 L2.39752134,8.40532301 Z M11.6014779,8.40858993 C11.5655967,8.41159375 11.5334311,8.43554097 11.5215402,8.47200118 C11.5056944,8.52061699 11.5320748,8.57250849 11.5807467,8.58834979 L12.5938833,8.91815145 C12.6425443,8.93398179 12.6944885,8.9076052 12.710343,8.85900255 C12.7262107,8.81038893 12.6998085,8.75849524 12.6511365,8.74265394 L11.6379999,8.41285228 C11.6258413,8.40888374 11.613439,8.40759012 11.6014779,8.4085987 L11.6014779,8.40858993 Z M2.01082336,9.12610992 C1.99881834,9.12632918 1.98666846,9.12891641 1.97497947,9.13411279 L1.56547633,9.31626036 C1.51872036,9.3370459 1.49785312,9.39139308 1.51866769,9.43810354 C1.53949543,9.484814 1.59387579,9.50566094 1.64062956,9.48486662 L2.05013709,9.30275633 C2.09689086,9.28197079 2.1177581,9.22762361 2.09694353,9.18091315 C2.08133919,9.1458803 2.04682308,9.12539076 2.01082336,9.12610553 L2.01082336,9.12610992 Z M11.9876996,9.12961803 C11.9516999,9.128741 11.9171772,9.14932921 11.9015399,9.18434671 C11.8806902,9.23104183 11.9015268,9.28540216 11.9482674,9.30622936 L12.3576125,9.48865538 C12.4043531,9.50948477 12.4587686,9.48866854 12.4796161,9.44197342 C12.5004657,9.39527831 12.4796292,9.34091797 12.4328886,9.32009077 L12.0235435,9.13766256 C12.0118677,9.13244425 11.9997002,9.12985702 11.9876996,9.12961583 L11.9876996,9.12961803 Z M2.80810427,9.3296109 C2.79037107,9.32829536 2.77205846,9.33224198 2.75543578,9.34184543 L1.83264417,9.87410879 C1.78832213,9.89967413 1.77324452,9.95589595 1.79883476,10.0001749 C1.824425,10.0444538 1.88070159,10.0595167 1.92502363,10.0339514 L2.84781524,9.50172747 C2.89213727,9.47616213 2.90721269,9.41990084 2.88162464,9.37562194 C2.86562526,9.34794735 2.83766473,9.33168069 2.80810427,9.32961748 L2.80810427,9.3296109 Z M11.191933,9.3296109 C11.1623726,9.33158421 11.1343682,9.34794077 11.1183732,9.37561536 C11.0927829,9.41989426 11.1078605,9.47615555 11.1521826,9.50172089 L12.0749742,10.0339448 C12.1192984,10.0595101 12.1756123,10.0444472 12.2012026,10.0001683 C12.2267928,9.95588937 12.2117152,9.89966755 12.1673953,9.87410221 L11.244562,9.34183885 C11.2279481,9.33225733 11.2096684,9.32837649 11.191933,9.32960432 L11.191933,9.3296109 Z M2.57793474,10.1107 C2.56015765,10.1113578 2.54235641,10.1170804 2.5268201,10.1283502 L2.16404439,10.3913158 C2.12261936,10.4213408 2.11345648,10.4788256 2.14350197,10.5202103 C2.17355843,10.561595 2.23109697,10.570749 2.272522,10.5407108 L2.63533721,10.2777452 C2.67676663,10.2477223 2.68592732,10.1902376 2.65587964,10.1488529 C2.63709298,10.1229872 2.60754788,10.1096805 2.57793255,10.1106934 L2.57793474,10.1107 Z M11.4198706,10.1138135 C11.3902552,10.1127172 11.3607277,10.126048 11.3419257,10.1518918 C11.3118407,10.1932546 11.3209662,10.2507722 11.3623803,10.2808257 L11.724998,10.5440303 C11.7664033,10.5740838 11.8239352,10.5649693 11.854018,10.5235956 C11.8841008,10.4822306 11.8749994,10.4247546 11.8336073,10.3947011 L11.4709896,10.1314965 C11.455473,10.1202267 11.4376455,10.1144383 11.4198771,10.1138025 L11.4198706,10.1138135 Z M3.39957467,10.145678 C3.37599697,10.1443625 3.35194521,10.1522119 3.33291274,10.1692986 L2.54045799,10.8809622 C2.50239744,10.9151421 2.4993051,10.9732649 2.53352272,11.0112906 C2.56773596,11.0493141 2.62591316,11.0524013 2.6639759,11.0182191 L3.45643285,10.3065555 C3.4944934,10.2723756 3.49758573,10.2142528 3.46336811,10.1762271 C3.44627137,10.1572175 3.42315676,10.1469322 3.39957467,10.145678 Z M10.5982284,10.1482214 C10.5746463,10.149537 10.5515186,10.1597324 10.5343977,10.178731 C10.5001537,10.2167326 10.5032175,10.274851 10.5412452,10.3090594 L11.3331842,11.02128 C11.3712228,11.0554928 11.4294373,11.052432 11.463679,11.0144392 C11.497923,10.9764398 11.4948592,10.9183192 11.4568316,10.8841129 L10.6648509,10.1718902 C10.6458228,10.1547882 10.6218105,10.1469936 10.5982284,10.1482302 L10.5982284,10.1482214 Z M4.15136596,10.8243172 C4.12175282,10.8232209 4.09219675,10.836464 4.07337936,10.8623144 L3.44654352,11.7231472 C3.41643438,11.7644947 3.42549631,11.8220035 3.46686647,11.8520812 C3.50825199,11.882161 3.56581907,11.8731079 3.59592601,11.8317561 L4.22276186,10.9709233 C4.2528688,10.929578 4.24380906,10.8720692 4.2024389,10.8419893 C4.18692235,10.8307195 4.16913428,10.8249311 4.15136596,10.8243172 Z M9.84348966,10.8281761 C9.82571256,10.8288339 9.80791132,10.8345127 9.79237501,10.8457825 C9.75094999,10.8758075 9.74179149,10.93329 9.77183259,10.9746769 L10.3975118,11.8363451 C10.4275639,11.877732 10.4851046,11.8868838 10.5265319,11.8568675 C10.5679591,11.8268447 10.5771176,11.7693622 10.5470743,11.7279752 L9.92139505,10.8663049 C9.90260839,10.8404392 9.87310279,10.8271763 9.84348746,10.8281871 L9.84348966,10.8281761 Z M3.34216342,10.9611334 C3.31858133,10.962449 3.29545574,10.9726444 3.27833266,10.991643 L2.97842863,11.3243937 C2.94418028,11.3623909 2.94721336,11.4205487 2.98525415,11.4547616 C3.02328836,11.4889744 3.08146337,11.485907 3.11570733,11.4478988 L3.41564867,11.1151504 C3.44989922,11.0771532 3.44682663,11.0189931 3.4088012,10.9847825 C3.38977312,10.9676805 3.36576087,10.9598881 3.34217659,10.9611225 L3.34216342,10.9611334 Z M10.6572769,10.961572 C10.6336948,10.9602564 10.6096716,10.9681277 10.5906545,10.985232 C10.5526137,11.019436 10.5495565,11.0775566 10.5837851,11.1155582 L10.8836474,11.4483878 C10.9178892,11.4863916 10.9760642,11.4894458 11.014105,11.4552286 C11.0521436,11.4210223 11.055203,11.3628645 11.0209525,11.3248607 L10.7210879,10.9920728 C10.7039692,10.9730632 10.6808393,10.9627998 10.6572572,10.961561 L10.6572769,10.961572 Z M5.02671247,11.3307258 C4.99071275,11.3298488 4.95623176,11.350437 4.9405945,11.3854545 L4.50644703,12.3576149 C4.48559735,12.40431 4.50643606,12.4586682 4.55317666,12.4794998 C4.59991506,12.5003292 4.65432835,12.4795107 4.67517803,12.4328178 L5.1093233,11.4606552 C5.13017298,11.4139623 5.10933428,11.3596019 5.06259367,11.3387725 C5.05091785,11.3335542 5.03871311,11.330967 5.02671247,11.3307258 Z M8.96742548,11.3334008 C8.95542045,11.33362 8.94323326,11.3362072 8.93154208,11.3414036 C8.88480148,11.3621672 8.8638662,11.4164859 8.88465663,11.4632073 L9.31744338,12.4359663 C9.33822722,12.4826614 9.39263831,12.5035764 9.43940524,12.4828084 C9.48614804,12.4620447 9.50708112,12.4077261 9.48629289,12.3610046 L9.05350394,11.3882456 C9.03792155,11.3532238 9.0034252,11.3327101 8.96742548,11.3333986 L8.96742548,11.3334008 Z M4.26383793,11.6312984 C4.23427966,11.6332717 4.20631036,11.6496282 4.19031975,11.6773028 L3.9662076,12.0651001 C3.94061955,12.109379 3.95569497,12.1656008 4.0000192,12.1911661 C4.04434124,12.2167315 4.10061783,12.2016685 4.12620588,12.1573896 L4.35031802,11.7695924 C4.37590607,11.7253135 4.36083065,11.6690916 4.31650642,11.6435263 C4.29989251,11.6339448 4.28157552,11.6300639 4.26383793,11.6312918 L4.26383793,11.6312984 Z M9.73615769,11.6312984 C9.71842448,11.6299828 9.70015138,11.6339514 9.68353089,11.6435329 C9.63920885,11.6690982 9.62413124,11.72532 9.64972148,11.769599 L9.87383143,12.1573962 C9.89942168,12.2016751 9.95569826,12.2167359 10.0000181,12.1911727 C10.0443423,12.1656074 10.05942,12.1093856 10.0338297,12.0651067 L9.80971976,11.6773094 C9.79372037,11.6496348 9.76571815,11.6333681 9.73615769,11.6313049 L9.73615769,11.6312984 Z M5.99320063,11.6451992 C5.95016469,11.6447607 5.91160155,11.6745665 5.9022982,11.7183301 L5.6808592,12.7596376 C5.67021489,12.80965 5.70197225,12.8584698 5.75202685,12.8690927 C5.80209024,12.8797267 5.85095531,12.8480002 5.86159084,12.7979943 L6.08302764,11.7566869 C6.09367196,11.7066745 6.0619146,11.6578547 6.01185999,11.6472317 C6.00560509,11.6459162 5.99935018,11.6452584 5.99320502,11.6452584 L5.99320063,11.6451992 Z M8.00352707,11.645857 C7.9973819,11.6459052 7.99117089,11.6465148 7.98491599,11.6478303 C7.93484602,11.6584204 7.90306671,11.7071853 7.91366494,11.7572066 L8.13434896,12.798674 C8.14494937,12.8486953 8.19379908,12.8804415 8.24387124,12.8698536 C8.29394121,12.8592635 8.32571832,12.8104591 8.3151201,12.7604379 L8.09439877,11.7190449 C8.08511517,11.6752747 8.0465696,11.6454996 8.00353366,11.6458329 L8.00352707,11.645857 Z M6.9999989,11.750892 C6.94882061,11.750892 6.90761944,11.7920508 6.90761944,11.8431815 L6.90761944,12.9077104 C6.90761944,12.9588411 6.94882061,13 6.9999989,13 C7.05117939,13 7.09237836,12.9588411 7.09237836,12.9077104 L7.09237836,11.8431815 C7.09237836,11.7920508 7.05117939,11.750892 6.9999989,11.750892 Z M5.30424589,12.0948751 C5.26836907,12.0979228 5.23617277,12.1218964 5.22430821,12.1583653 L5.08575877,12.5842409 C5.06993496,12.6328677 5.09638114,12.6847416 5.14504649,12.7005501 C5.19371843,12.7163585 5.24564292,12.6898942 5.26146673,12.6412806 L5.40001397,12.2154444 C5.41583779,12.1668199 5.38939161,12.1149459 5.34072845,12.0991375 C5.32856979,12.0951909 5.31620703,12.0938753 5.30424589,12.0948839 L5.30424589,12.0948751 Z M8.69503425,12.0950944 C8.68307311,12.0939981 8.67072132,12.0953137 8.65855388,12.0993261 C8.60987975,12.1151345 8.58341163,12.1670062 8.59922446,12.2156352 L8.7377344,12.6415086 C8.75355821,12.6901376 8.8054805,12.7165383 8.85415464,12.7007386 C8.90282877,12.6849302 8.9292969,12.6330979 8.91348186,12.5844711 L8.77493462,12.1585956 C8.76306127,12.1221244 8.73091326,12.0981508 8.69503425,12.0951054 L8.69503425,12.0950944 Z M6.42012971,12.3322886 C6.3772891,12.3364106 6.34199827,12.3700073 6.33731916,12.4145011 L6.29047102,12.8598533 C6.28511594,12.9107033 6.32178505,12.955914 6.37268461,12.9612639 C6.42358417,12.9666138 6.46887846,12.9299803 6.47423354,12.8791303 L6.52107949,12.4338176 C6.52643456,12.3829676 6.48976546,12.3377174 6.43887028,12.3323675 C6.43250564,12.3317097 6.42625074,12.3317097 6.42012752,12.3322908 L6.42012971,12.3322886 Z M7.57615905,12.3327271 C7.57003582,12.3320693 7.56373702,12.3320693 7.55737238,12.3328038 C7.50647063,12.3381098 7.4697664,12.3833206 7.47508198,12.4341728 L7.5216492,12.8795666 C7.52696038,12.9304189 7.57221516,12.9670501 7.62311912,12.9617397 C7.67402087,12.9564337 7.71072729,12.9112207 7.70541172,12.8603685 L7.658884,12.4150163 C7.65423123,12.3705182 7.61898868,12.3368798 7.57615027,12.3327227 L7.57615905,12.3327271 Z"/>
          <g transform="rotate(48 3.581 12.14)">
            <path fill="url(#safari-c)" d="M3.23500132,6.22975382 L2.26066294,12.4396527 L1.28632456,6.22975382 L2.26066294,0.0198549402 L3.23500132,6.22975382 Z" filter="url(#safari-d)"/>
            <g transform="translate(1)">
              <mask id="safari-f" fill="#fff">
                <use xlink:href="#safari-e"/>
              </mask>
              <use fill="#FE504D" xlink:href="#safari-e"/>
              <rect width="3.64" height="6.053" x="-.371" y=".117" fill="#FE504D" mask="url(#safari-f)"/>
              <rect width="3.92" height="12.42" x="1.072" y="-6.201" fill="#000" fill-opacity=".25" mask="url(#safari-f)" style="mix-blend-mode:multiply"/>
            </g>
            <g transform="rotate(-180 1.573 6.173)">
              <mask id="safari-h" fill="#fff">
                <use xlink:href="#safari-g"/>
              </mask>
              <use fill="#EEE" xlink:href="#safari-g"/>
              <rect width="3.64" height="6.053" x="-.371" y=".117" fill="#EEE" mask="url(#safari-h)"/>
              <rect width="3.92" height="12.42" x="-2.844" y="-6.185" fill="#000" fill-opacity=".25" mask="url(#safari-h)" style="mix-blend-mode:multiply"/>
            </g>
          </g>
        </g>
      </svg>
        """.trimIndent()

    val image = renderSvg(svg.byteInputStream())

    val goldImage = loadOrSaveGoldSnapshot(image, "filter")
    ImageComparator.compareAndAssert(null, image, goldImage, null)
  }

  @Test
  fun dos() {
    assumeTrue(System.getenv("TEAMCITY_VERSION") == null)
    @Language("HTML")
    val svg = """
      <?xml version="1.0" standalone="no"?>
      <svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
          <defs>
              <g id="a0">
                  <circle stroke="#000000" fill="#ffffff" fill-opacity="0.1" r="10"/>
              </g>
          </defs>
          <defs>
              <g id="a1">
                  <use x="0" y="10" xlink:href="#a0"/>
                  <use x="10" y="10" xlink:href="#a0"/>
                  <use x="20" y="10" xlink:href="#a0"/>
                  <use x="30" y="10" xlink:href="#a0"/>
                  <use x="40" y="10" xlink:href="#a0"/>
                  <use x="50" y="10" xlink:href="#a0"/>
                  <use x="60" y="10" xlink:href="#a0"/>
                  <use x="70" y="10" xlink:href="#a0"/>
                  <use x="80" y="10" xlink:href="#a0"/>
                  <use x="90" y="10" xlink:href="#a0"/>
              </g>
          </defs>
          <defs>
              <g id="a2">
                  <use x="0" y="10" xlink:href="#a1"/>
                  <use x="10" y="10" xlink:href="#a1"/>
                  <use x="20" y="10" xlink:href="#a1"/>
                  <use x="30" y="10" xlink:href="#a1"/>
                  <use x="40" y="10" xlink:href="#a1"/>
                  <use x="50" y="10" xlink:href="#a1"/>
                  <use x="60" y="10" xlink:href="#a1"/>
                  <use x="70" y="10" xlink:href="#a1"/>
                  <use x="80" y="10" xlink:href="#a1"/>
                  <use x="90" y="10" xlink:href="#a1"/>
              </g>
          </defs>
          <defs>
              <g id="a3">
                  <use x="0" y="10" xlink:href="#a2"/>
                  <use x="10" y="10" xlink:href="#a2"/>
                  <use x="20" y="10" xlink:href="#a2"/>
                  <use x="30" y="10" xlink:href="#a2"/>
                  <use x="40" y="10" xlink:href="#a2"/>
                  <use x="50" y="10" xlink:href="#a2"/>
                  <use x="60" y="10" xlink:href="#a2"/>
                  <use x="70" y="10" xlink:href="#a2"/>
                  <use x="80" y="10" xlink:href="#a2"/>
                  <use x="90" y="10" xlink:href="#a2"/>
              </g>
          </defs>
          <defs>
              <g id="a4">
                  <use x="0" y="10" xlink:href="#a3"/>
                  <use x="10" y="10" xlink:href="#a3"/>
                  <use x="20" y="10" xlink:href="#a3"/>
                  <use x="30" y="10" xlink:href="#a3"/>
                  <use x="40" y="10" xlink:href="#a3"/>
                  <use x="50" y="10" xlink:href="#a3"/>
                  <use x="60" y="10" xlink:href="#a3"/>
                  <use x="70" y="10" xlink:href="#a3"/>
                  <use x="80" y="10" xlink:href="#a3"/>
                  <use x="90" y="10" xlink:href="#a3"/>
              </g>
          </defs>
          <defs>
              <g id="a5">
                  <use x="0" y="10" xlink:href="#a4"/>
                  <use x="10" y="10" xlink:href="#a4"/>
                  <use x="20" y="10" xlink:href="#a4"/>
                  <use x="30" y="10" xlink:href="#a4"/>
                  <use x="40" y="10" xlink:href="#a4"/>
                  <use x="50" y="10" xlink:href="#a4"/>
                  <use x="60" y="10" xlink:href="#a4"/>
                  <use x="70" y="10" xlink:href="#a4"/>
                  <use x="80" y="10" xlink:href="#a4"/>
                  <use x="90" y="10" xlink:href="#a4"/>
              </g>
          </defs>
          <defs>
              <g id="a6">
                  <use x="0" y="10" xlink:href="#a5"/>
                  <use x="10" y="10" xlink:href="#a5"/>
                  <use x="20" y="10" xlink:href="#a5"/>
                  <use x="30" y="10" xlink:href="#a5"/>
                  <use x="40" y="10" xlink:href="#a5"/>
                  <use x="50" y="10" xlink:href="#a5"/>
                  <use x="60" y="10" xlink:href="#a5"/>
                  <use x="70" y="10" xlink:href="#a5"/>
                  <use x="80" y="10" xlink:href="#a5"/>
                  <use x="90" y="10" xlink:href="#a5"/>
              </g>
          </defs>
          <defs>
              <g id="a7">
                  <use x="0" y="10" xlink:href="#a6"/>
                  <use x="10" y="10" xlink:href="#a6"/>
                  <use x="20" y="10" xlink:href="#a6"/>
                  <use x="30" y="10" xlink:href="#a6"/>
                  <use x="40" y="10" xlink:href="#a6"/>
                  <use x="50" y="10" xlink:href="#a6"/>
                  <use x="60" y="10" xlink:href="#a6"/>
                  <use x="70" y="10" xlink:href="#a6"/>
                  <use x="80" y="10" xlink:href="#a6"/>
                  <use x="90" y="10" xlink:href="#a6"/>
              </g>
          </defs>
          <defs>
              <g id="a8">
                  <use x="0" y="10" xlink:href="#a7"/>
                  <use x="10" y="10" xlink:href="#a7"/>
                  <use x="20" y="10" xlink:href="#a7"/>
                  <use x="30" y="10" xlink:href="#a7"/>
                  <use x="40" y="10" xlink:href="#a7"/>
                  <use x="50" y="10" xlink:href="#a7"/>
                  <use x="60" y="10" xlink:href="#a7"/>
                  <use x="70" y="10" xlink:href="#a7"/>
                  <use x="80" y="10" xlink:href="#a7"/>
                  <use x="90" y="10" xlink:href="#a7"/>
              </g>
          </defs>
          <defs>
              <g id="a9">
                  <use x="0" y="10" xlink:href="#a8"/>
                  <use x="10" y="10" xlink:href="#a8"/>
                  <use x="20" y="10" xlink:href="#a8"/>
                  <use x="30" y="10" xlink:href="#a8"/>
                  <use x="40" y="10" xlink:href="#a8"/>
                  <use x="50" y="10" xlink:href="#a8"/>
                  <use x="60" y="10" xlink:href="#a8"/>
                  <use x="70" y="10" xlink:href="#a8"/>
                  <use x="80" y="10" xlink:href="#a8"/>
                  <use x="90" y="10" xlink:href="#a8"/>
              </g>
          </defs>
          <defs>
              <g id="a10">
                  <use x="0" y="10" xlink:href="#a9"/>
                  <use x="10" y="10" xlink:href="#a9"/>
                  <use x="20" y="10" xlink:href="#a9"/>
                  <use x="30" y="10" xlink:href="#a9"/>
                  <use x="40" y="10" xlink:href="#a9"/>
                  <use x="50" y="10" xlink:href="#a9"/>
                  <use x="60" y="10" xlink:href="#a9"/>
                  <use x="70" y="10" xlink:href="#a9"/>
                  <use x="80" y="10" xlink:href="#a9"/>
                  <use x="90" y="10" xlink:href="#a9"/>
              </g>
          </defs>
          <use x="0" y="0" xlink:href="#a9"/>
      </svg>
    """.trimIndent()

    assertThatThrownBy {
      val image = renderSvg(svg.byteInputStream())
    }.hasMessage("use is over-nested: 7")
  }

  @Test
  fun dosShort() {
    assumeTrue(System.getenv("TEAMCITY_VERSION") == null)
    @Language("HTML")
    val svg = """
      <?xml version="1.0" standalone="no"?>
      <svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
          <defs>
              <g id="a0">
                  <circle stroke="#000000" fill="#ffffff" fill-opacity="0.1" r="10"/>
              </g>
          </defs>
          <defs>
              <g id="a1">
                  <use x="0" y="10" xlink:href="#a0"/>
                  <use x="10" y="10" xlink:href="#a0"/>
                  <use x="20" y="10" xlink:href="#a0"/>
                  <use x="30" y="10" xlink:href="#a0"/>
                  <use x="40" y="10" xlink:href="#a0"/>
                  <use x="50" y="10" xlink:href="#a0"/>
                  <use x="60" y="10" xlink:href="#a0"/>
                  <use x="70" y="10" xlink:href="#a0"/>
                  <use x="80" y="10" xlink:href="#a0"/>
                  <use x="90" y="10" xlink:href="#a0"/>
              </g>
          </defs>
          <defs>
              <g id="a2">
                  <use x="0" y="10" xlink:href="#a1"/>
                  <use x="10" y="10" xlink:href="#a1"/>
                  <use x="20" y="10" xlink:href="#a1"/>
                  <use x="30" y="10" xlink:href="#a1"/>
                  <use x="40" y="10" xlink:href="#a1"/>
                  <use x="50" y="10" xlink:href="#a1"/>
                  <use x="60" y="10" xlink:href="#a1"/>
                  <use x="70" y="10" xlink:href="#a1"/>
                  <use x="80" y="10" xlink:href="#a1"/>
                  <use x="90" y="10" xlink:href="#a1"/>
              </g>
          </defs>
          <use x="0" y="0" xlink:href="#a2"/>
      </svg>
    """.trimIndent()

    val image = renderSvg(svg.byteInputStream())
  }

  @Test
  fun css() {
    assumeTrue(System.getenv("TEAMCITY_VERSION") == null)

    @Language("HTML")
    val svg = """<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
        <defs>
            <style>.cls-1{fill:url(#linear-gradient);}</style>
            <linearGradient id="linear-gradient" x1="63.67" y1="0.33" x2="3.03" y2="60.97" gradientUnits="userSpaceOnUse">
                <stop offset="0" stop-color="#e44857"/>
                <stop offset="0.47" stop-color="#c711e1"/>
                <stop offset="1" stop-color="#7f52ff"/>
            </linearGradient>
        </defs>
        <path class="cls-1" d="M64,64H1.16L24.94,26.48,37.75,45.17H41.9L64,13.56ZM26.85,14.15l13,19L63.05,0H0V49.87L22.63,14.15Z"/>
    </svg>""".trimIndent()
    val image = renderSvg(svg.byteInputStream())

    val goldImage = loadOrSaveGoldSnapshot(image, "css")
    ImageComparator.compareAndAssert(null, image, goldImage, null)
  }

  @Test
  fun svg2() {
    assumeTrue(System.getenv("TEAMCITY_VERSION") == null)

    @Language("HTML")
    val svg = """<!-- Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
      <g fill="#7F8B91" fill-opacity=".5" fill-rule="evenodd" transform="translate(1 1)">
        <rect width="2" height="4" x="2.471" y="1.471" transform="rotate(-45 3.471 3.471)"/>
        <rect width="4" height="2" y="6"/>
        <rect width="2" height="4" x="2.471" y="8.531" transform="rotate(45 3.471 10.531)"/>
        <rect width="2" height="4" x="6" y="10"/>
        <rect width="2" height="4" x="9.531" y="8.531" transform="rotate(-45 10.531 10.531)"/>
        <rect width="4" height="2" x="10" y="6"/>
        <rect width="2" height="4" x="9.531" y="1.471" transform="rotate(45 10.531 3.471)"/>
        <rect width="2" height="4" x="6"/>
      </g>
    </svg>
    """.trimIndent()
    val image = renderSvg(svg.byteInputStream(), scale = 2f)

    val goldImage = loadOrSaveGoldSnapshot(image, "svg2")
    ImageComparator.compareAndAssert(null, image, goldImage, null)
  }

  @Test
  fun filer3() {
    assumeTrue(System.getenv("TEAMCITY_VERSION") == null)

    @Language("HTML")
    val svg = """
      <?xml version="1.0" encoding="UTF-8"?>
      <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" height="16px" viewBox="0 0 16 16" version="1.1">
          <defs>
              <filter id="alpha" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
                  <feColorMatrix type="matrix" in="SourceGraphic" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"/>
              </filter>
              <mask id="mask0">
                  <g filter="url(#alpha)">
                      <rect x="0" y="0" width="16" height="16" style="fill:rgb(0%,0%,0%);fill-opacity:0.2;stroke:none;"/>
                  </g>
              </mask>
              <clipPath id="clip1">
                  <rect x="0" y="0" width="16" height="16"/>
              </clipPath>
              <g id="surface5" clip-path="url(#clip1)">
                  <path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 0.640625 1.28125 C 0.289062 1.28125 0 1.566406 0 1.921875 L 0 14.273438 C 0 14.625 0.289062 14.910156 0.640625 14.910156 L 1.34375 14.910156 L 13.953125 1.28125 Z M 0.640625 1.28125 "/>
              </g>
          </defs>
          <g id="surface1">
              <path style=" stroke:none;fill-rule:nonzero;fill:rgb(62.7451%,63.137257%,63.529414%);fill-opacity:1;" d="M 0 14.335938 C 0 14.65625 0.257812 14.945312 0.574219 14.945312 L 15.390625 14.945312 C 15.710938 14.945312 16 14.6875 16 14.335938 L 16 3.742188 L 0 3.742188 Z M 0 14.335938 "/>
              <path style=" stroke:none;fill-rule:nonzero;fill:rgb(47.843137%,47.843137%,47.843137%);fill-opacity:1;" d="M 15.390625 1.28125 L 0.574219 1.28125 C 0.257812 1.28125 0 1.566406 0 1.886719 L 0 3.710938 L 16 3.710938 L 16 1.886719 C 16 1.566406 15.742188 1.28125 15.390625 1.28125 "/>
              <path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,44.705883%,77.64706%);fill-opacity:1;" d="M 1.183594 4.832031 L 7.710938 4.832031 L 7.710938 8.992188 L 1.183594 8.992188 Z M 1.183594 4.832031 "/>
              <path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,44.705883%,77.64706%);fill-opacity:1;" d="M 1.183594 9.566406 L 7.710938 9.566406 L 7.710938 13.726562 L 1.183594 13.726562 Z M 1.183594 9.566406 "/>
              <path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 8.289062 4.832031 L 14.785156 4.832031 L 14.785156 8.992188 L 8.289062 8.992188 Z M 8.289062 4.832031 "/>
              <path style=" stroke:none;fill-rule:nonzero;fill:rgb(0%,44.705883%,77.64706%);fill-opacity:1;" d="M 8.289062 9.566406 L 14.785156 9.566406 L 14.785156 13.726562 L 8.289062 13.726562 Z M 8.289062 9.566406 "/>
              <use xlink:href="#surface5" mask="url(#mask0)"/>
          </g>
      </svg>
    """.trimIndent()
    val image = renderSvg(svg.byteInputStream(), scale = 2f)

    val goldImage = loadOrSaveGoldSnapshot(image, "filter3")
    ImageComparator.compareAndAssert(null, image, goldImage, null)
  }

  @Test
  fun base64EncodedPng() {
    assumeTrue(System.getenv("TEAMCITY_VERSION") == null)

    @Language("HTML")
    val svg = """
  <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="text/ecmascript" width="800.0" zoomAndPan="magnify" shape-rendering="geometricPrecision" class="plt-container" contentStyleType="text/css" height="600.0" preserveAspectRatio="xMidYMid meet" version="1.0">
    <g id="pGkz290">
      <rect x="0.0" y="0.0" fill-opacity="1.0" fill="rgb(255,255,255)" width="800.0" height="600.0" stroke="rgb(71,71,71)" stroke-width="0.0" stroke-opacity="1.0"/>
      <g transform="translate(135.0 57.0 ) ">
        <g transform="translate(0.0 530.0 ) "/>
        <g transform=""/>
        <g clip-bounds-jfx="[rect (0.0, 0.0), (530.0, 530.0)]" clip-path="url(#ca9yVpa)" transform="">
          <defs>
            <clipPath id="ca9yVpa">
              <rect x="0.0" width="530.0" height="530.0" y="0.0"/>
            </clipPath>
          </defs>
          <image x="24.090909090909093" y="24.090909090909093" width="481.81818181818176" xlink:href="" xlink:type="simple" xlink:actuate="onLoad" height="481.81818181818176" preserveAspectRatio="none" xlink:show="embed"/>
        </g>
      </g>
      <g transform="translate(135.0 15.2 ) ">
        <text class="plot-title" y="0.0">Elliptic curve with a = -1.0, b = 0.0</text>
      </g>
      <g transform="translate(135.0 38.5 ) ">
        <text class="plot-subtitle" y="0.0">Simple way to draw an algebraic curve - with geomRaster()</text>
      </g>
    </g>
    <g id="d1zf0LL">
      <g>
        <g/>
        <g/>
      </g>
    </g>
  </svg>
""".trimIndent()
    val image = renderSvg(svg.byteInputStream())

    val goldImage = loadOrSaveGoldSnapshot(image, "base64")
    ImageComparator.compareAndAssert(null, image, goldImage, null)
  }

  @Test
  fun shadow() {
    assumeTrue(System.getenv("TEAMCITY_VERSION") == null)

    @Language("HTML")
    val svg = """
<svg width="4" height="6" viewBox="0 0 4 6" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_5382_56966)">
<g filter="url(#filter0_d_5382_56966)">
<path d="M11 4.99023H-7C-7.55228 4.99023 -8 5.43794 -8 5.99023V24.9902C-8 25.5425 -7.55228 25.9902 -7 25.9902H11C11.5523 25.9902 12 25.5425 12 24.9902V5.99023C12 5.43795 11.5523 4.99023 11 4.99023Z" fill="white" fill-opacity="0.01"/>
</g>
</g>
<defs>
<filter id="filter0_d_5382_56966" x="-20" y="-3.00977" width="44" height="45" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="6"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.16 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_5382_56966"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_5382_56966" result="shape"/>
</filter>
<clipPath id="clip0_5382_56966">
<rect width="4" height="6" fill="white"/>
</clipPath>
</defs>
</svg>

""".trimIndent()
    val image = renderSvg(svg.byteInputStream())

    val goldImage = loadOrSaveGoldSnapshot(image, "shadow")
    ImageComparator.compareAndAssert(null, image, goldImage, null)
  }
  @Test
  fun topLeftIcon() {
    assumeTrue(System.getenv("TEAMCITY_VERSION") == null)

    @Language("HTML")
    val svg = """
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="14" fill="none">
  <g clip-path="url(#a)" filter="url(#b)">
    <path fill="#fff" fill-opacity=".01" d="M30 5H10v21h20V5Z"/>
  </g>
  <defs>
    <clipPath id="a">
      <path fill="#fff" d="M0 0h18v14H0z"/>
    </clipPath>
    <filter id="b" width="44" height="45" x="-2" y="-3" color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse">
      <feFlood flood-opacity="0" result="BackgroundImageFix"/>
      <feColorMatrix in="SourceAlpha" result="hardAlpha" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
      <feOffset dy="4"/>
      <feGaussianBlur stdDeviation="6"/>
      <feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.16 0"/>
      <feBlend in2="BackgroundImageFix" result="effect1_dropShadow_5382_56962"/>
      <feBlend in="SourceGraphic" in2="effect1_dropShadow_5382_56962" result="shape"/>
    </filter>
  </defs>
</svg>
""".trimIndent()
    val image = renderSvg(svg.byteInputStream())

    val goldImage = loadOrSaveGoldSnapshot(image, "shadow")
    ImageComparator.compareAndAssert(null, image, goldImage, null)
  }

  @Test
  fun f1() {
    assumeTrue(System.getenv("TEAMCITY_VERSION") == null)

    @Language("HTML")
    val svg = """
<!-- Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="18" height="22" viewBox="0 0 18 22">
  <defs>
    <rect id="bottomleft-b" width="20" height="21"/>
    <filter id="bottomleft-a" width="270%" height="261.9%" x="-85%" y="-61.9%" filterUnits="objectBoundingBox">
      <feOffset dy="4" in="SourceAlpha" result="shadowOffsetOuter1"/>
      <feGaussianBlur in="shadowOffsetOuter1" result="shadowBlurOuter1" stdDeviation="5"/>
      <feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/>
      <feColorMatrix in="shadowBlurOuter1" values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.3 0"/>
    </filter>
  </defs>
  <g fill="none" fill-rule="evenodd" transform="translate(10 -13)">
    <use fill="#000" filter="url(#bottomleft-a)" xlink:href="#bottomleft-b"/>
    <use fill="#FFF" fill-opacity="0" xlink:href="#bottomleft-b"/>
  </g>
</svg>
""".trimIndent()
    val image = renderSvg(svg.byteInputStream())

    val goldImage = loadOrSaveGoldSnapshot(image, "f1")
    ImageComparator.compareAndAssert(null, image, goldImage, null)
  }

  @Test
  fun stdDev() {
    assumeTrue(System.getenv("TEAMCITY_VERSION") == null)

    @Language("HTML")
    val svg = """
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" viewBox="0 0 16 16">
  <defs>
    <linearGradient id="nwjs-a" x1="50%" x2="50%" y1="0%" y2="100%">
      <stop offset="0%" stop-color="#ABABAB"/>
      <stop offset="100%" stop-color="#3E3E3E"/>
    </linearGradient>
    <linearGradient id="nwjs-b" x1="50%" x2="50%" y1="0%" y2="100%">
      <stop offset="0%" stop-color="#CACACC"/>
      <stop offset="100%" stop-color="#6D6F79"/>
    </linearGradient>
    <radialGradient id="nwjs-c" cy="48.197%" r="59.046%" fx="50%" fy="48.197%" gradientTransform="matrix(0 .87734 -.99871 0 .981 .043)">
      <stop offset="0%" stop-color="#5B6376"/>
      <stop offset="100%" stop-color="#181C21"/>
    </radialGradient>
    <path id="nwjs-d" d="M7.5,2.28867513 L11.6961524,4.71132487 C12.0055535,4.88995766 12.1961524,5.22008468 12.1961524,5.57735027 L12.1961524,10.4226497 C12.1961524,10.7799153 12.0055535,11.1100423 11.6961524,11.2886751 L7.5,13.7113249 C7.19059892,13.8899577 6.80940108,13.8899577 6.5,13.7113249 L2.30384758,11.2886751 C1.9944465,11.1100423 1.80384758,10.7799153 1.80384758,10.4226497 L1.80384758,5.57735027 C1.80384758,5.22008468 1.9944465,4.88995766 2.30384758,4.71132487 L6.5,2.28867513 C6.80940108,2.11004234 7.19059892,2.11004234 7.5,2.28867513 Z"/>
    <filter id="nwjs-e" width="138.5%" height="133.8%" x="-19.2%" y="-16.9%" filterUnits="objectBoundingBox">
      <feGaussianBlur in="SourceAlpha" result="shadowBlurInner1" stdDeviation="1.5"/>
      <feOffset dy="1" in="shadowBlurInner1" result="shadowOffsetInner1"/>
      <feComposite in="shadowOffsetInner1" in2="SourceAlpha" k2="-1" k3="1" operator="arithmetic" result="shadowInnerInner1"/>
      <feColorMatrix in="shadowInnerInner1" values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.5 0"/>
    </filter>
    <linearGradient id="nwjs-f" x1="50%" x2="50%" y1="0%" y2="100%">
      <stop offset="0%" stop-color="#676767" stop-opacity=".387"/>
      <stop offset="100%" stop-opacity=".387"/>
    </linearGradient>
    <filter id="nwjs-g" width="100%" height="100%" x="0%" y="0%" filterUnits="objectBoundingBox">
      <feGaussianBlur in="SourceGraphic"/>
    </filter>
    <polygon id="nwjs-h" points=".729 .922 1.458 5.908 0 5.908"/>
    <polygon id="nwjs-j" points=".729 .922 1.458 5.908 0 5.908"/>
  </defs>
  <g fill="none" fill-rule="evenodd" transform="translate(1)">
    <path fill="url(#nwjs-a)" fill-rule="nonzero" d="M7.46531337,1.06949476 L12.7439975,4.11714449 C13.0533986,4.29577728 13.2439975,4.6259043 13.2439975,4.98316989 L13.2439975,11.0784694 C13.2439975,11.4357349 13.0533986,11.765862 12.7439975,11.9444948 L7.46531337,14.9921445 C7.15591229,15.1707773 6.77471445,15.1707773 6.46531337,14.9921445 L1.18662919,11.9444948 C0.877228116,11.765862 0.686629193,11.4357349 0.686629193,11.0784694 L0.686629193,4.98316989 C0.686629193,4.6259043 0.877228116,4.29577728 1.18662919,4.11714449 L6.46531337,1.06949476 C6.77471445,0.890861964 7.15591229,0.890861964 7.46531337,1.06949476 Z"/>
    <path fill="url(#nwjs-b)" fill-rule="nonzero" d="M7.5,1.28867513 L12.5621778,4.21132487 C12.8715789,4.38995766 13.0621778,4.72008468 13.0621778,5.07735027 L13.0621778,10.9226497 C13.0621778,11.2799153 12.8715789,11.6100423 12.5621778,11.7886751 L7.5,14.7113249 C7.19059892,14.8899577 6.80940108,14.8899577 6.5,14.7113249 L1.43782217,11.7886751 C1.1284211,11.6100423 0.937822174,11.2799153 0.937822174,10.9226497 L0.937822174,5.07735027 C0.937822174,4.72008468 1.1284211,4.38995766 1.43782217,4.21132487 L6.5,1.28867513 C6.80940108,1.11004234 7.19059892,1.11004234 7.5,1.28867513 Z"/>
    <g fill-rule="nonzero">
      <use fill="url(#nwjs-c)" xlink:href="#nwjs-d"/>
      <use fill="#000" filter="url(#nwjs-e)" xlink:href="#nwjs-d"/>
    </g>
    <g transform="rotate(60 2.503 11.523)">
      <path fill="url(#nwjs-f)" d="M2.51755318,5.95455977 L1.85598296,11.069148 L1.19441274,5.95455977 L1.85598296,0.839971505 L2.51755318,5.95455977 Z" filter="url(#nwjs-g)"/>
      <g transform="translate(1)">
        <mask id="nwjs-i" fill="#fff">
          <use xlink:href="#nwjs-h"/>
        </mask>
        <use fill="#0082FE" xlink:href="#nwjs-h"/>
        <rect width="2.662" height="10.229" x=".729" y=".664" fill="#000" fill-opacity=".25" mask="url(#nwjs-i)" opacity=".83" style="mix-blend-mode:multiply"/>
      </g>
      <g transform="rotate(-180 1.227 5.907)">
        <mask id="nwjs-k" fill="#fff">
          <use xlink:href="#nwjs-j"/>
        </mask>
        <use fill="#DCDCDC" xlink:href="#nwjs-j"/>
        <rect width="2.662" height="10.229" x="-1.937" y="-2.206" fill="#000" fill-opacity=".25" mask="url(#nwjs-k)" opacity=".83" style="mix-blend-mode:multiply"/>
      </g>
    </g>
  </g>
</svg>
""".trimIndent()
    renderSvg(svg.byteInputStream())
  }

  @Test
  fun base64Encoded2() {
    assumeTrue(System.getenv("TEAMCITY_VERSION") == null)

    val image = testDataDir.resolve("base64-2.svg").inputStream().use { renderSvg(it) }

    val goldImage = loadOrSaveGoldSnapshot(image, "base64-2")
    ImageComparator.compareAndAssert(null, image, goldImage, null)
  }
}

private val testDataDir: Path
  get() = Path.of(PlatformTestUtil.getPlatformTestDataPath(), "svg")

private fun loadOrSaveGoldSnapshot(image: BufferedImage, name: String): Image {
  val file = testDataDir.resolve("$name.png")
  if (false && Files.exists(file)) {
    return ImageIO.read(file.toFile())
  }
  else {
    Files.createDirectories(file.parent)
    ImageIO.write(image, "PNG", file.toFile())
    return image
  }
}
